import { DownOutlined, SearchOutlined } from '@ant-design/icons'
import { Menu, Popover } from 'antd'
import { connect } from 'dva'
import { isEmpty } from 'lodash-es'
import { useEffect, useState } from 'react'

import AekTreeSelect from '@/components/AekTreeSelect'
import { routesMap } from '@/router/index'
import { navigateTo } from '@/router/navigate'
import { getIdList } from '@/utils/dataHelper'
import { getBasicFn } from '@/utils/dvaUtil/index'
import { cx } from '@/utils/stringUtil'
import { hasProtocol, joinParams } from '@/utils/urlUtil'

import ICON_SYSTEM_BTN from './imgs/icon_system_btn.png'
import ICON_SYSTEM_HOME from './imgs/icon_system_home.png'
import styles from './index.module.less'

const namespace = 'app'

const { toAction } = getBasicFn({
  namespace,
})

/**
 * @param {{modelState: import('@/models/app').state}} param0
 */
function Aside({ modelState, collapsed, pathname }) {
  const { loginInfo, userInfo, currentEntranceId, menuList } = modelState
  const userEntrancesList = loginInfo?.authorization?.details?.entrances || []

  const paths = pathname.split('/')
  const pageKey = paths.pop()

  const [items, setItems] = useState([])
  const [openKeys, setOpenKeys] = useState([])
  const [oldOpenKeys, setOldOpenKeys] = useState([])
  const [selectedKeys, setSelectedKeys] = useState([])
  const [popoverVisible, setPopoverVisible] = useState(false)

  let pageKeys = getIdList({ dataSource: items, fieldName: 'key', fieldValue: pageKey })
  // 未找到路径列表，并且路径大于1，则打开的是不在菜单配置中的路径，如详情页
  // 这个时候需要从项目配置里找到该页面的上级页面，再从菜单里找
  if (isEmpty(pageKeys) && paths.length > 1) {
    const _paths = routesMap[pageKey].path.split('/')
    _paths.pop()
    const _pageKey = _paths.pop()
    pageKeys = getIdList({ dataSource: items, fieldName: 'key', fieldValue: _pageKey })
  }

  const getItems = menuList => {
    const deepGetMenus = menus => {
      return menus.map(menu => {
        const { children, featurePath, menuName, icon } = menu
        let _children
        if (Array.isArray(children) && children.length) {
          _children = deepGetMenus(children)
        }
        return {
          key: featurePath,
          label: menuName,
          icon: icon ? <img src={icon} alt='图片' width={20} height={20} /> : undefined,
          children: _children,
        }
      })
    }
    return deepGetMenus(menuList)
  }

  useEffect(() => {
    if (collapsed) {
      setOldOpenKeys(openKeys)
      setOpenKeys([])
    } else {
      setOpenKeys([...oldOpenKeys, ...openKeys, ...pageKeys])
      setOldOpenKeys([])
    }
  }, [collapsed])

  useEffect(() => {
    setItems(getItems(menuList))
  }, [JSON.stringify(menuList)])

  useEffect(() => {
    setSelectedKeys(pageKeys)
    collapsed ? setOldOpenKeys([...oldOpenKeys, ...openKeys, ...pageKeys]) : setOpenKeys([...openKeys, ...pageKeys])
  }, [pathname, items])

  const onClick = options => {
    const { key } = options
    if (pageKey === key) return
    navigateTo(key)
  }

  const renderSystemSwitch = (
    <div className={styles.systemSwitch}>
      <div className={styles.systemSwitchGroup}>
        {userEntrancesList.map(item => {
          const children = (
            <>
              <img src={item.icon || ICON_SYSTEM_HOME} alt={item.entranceName} width={44} height={44} />
              <div className='mt8px'>{item.entranceName}</div>
            </>
          )
          if (item.type === 2) {
            let url = item.externalUrl
            if (url && !hasProtocol(url)) {
              url = `//${url}`
            }
            url = joinParams({ userMobile: userInfo.mobileNumber || userInfo.userMobile }, url)
            return (
              <a
                key={url}
                href={url}
                target='_blank'
                className={`${styles.systemSwitchItem} flex flex-col items-center justify-center`}
                style={!url ? { pointerEvents: 'none', cursor: 'not-allowed' } : undefined}
                title={!url ? '暂无可访问链接' : undefined}
              >
                {children}
              </a>
            )
          }
          return (
            <div
              key={item.entranceId}
              className={cx(
                styles.systemSwitchItem,
                'flex cursor-pointer flex-col items-center justify-center',
                currentEntranceId === item.entranceId && 'outline-blue outline outline-1',
              )}
              onClick={async () => {
                if (currentEntranceId === item.entranceId) return
                await toAction('changeEntrance', { entranceId: item.entranceId })
                setPopoverVisible(false)
              }}
            >
              {children}
            </div>
          )
        })}
      </div>
    </div>
  )

  const popoverBody = (
    <div
      className={cx(
        'flex cursor-pointer items-center justify-between',
        styles.appLogoArea,
        collapsed && styles.collapsed,
      )}
    >
      <div className='flex-grow-1 flex items-center'>
        <img src={ICON_SYSTEM_BTN} alt='' className={styles.img} />
        {!collapsed && (
          <span className='ml8px fs14px c-#597095 whitespace-nowrap'>
            {loginInfo.superAdmin
              ? '系统管理'
              : userEntrancesList.find(({ entranceId }) => currentEntranceId === entranceId)?.entranceName}
          </span>
        )}
      </div>
      {userEntrancesList.length > 1 && !collapsed && <DownOutlined />}
    </div>
  )

  return (
    <div className='h-100% flex flex-col'>
      {isEmpty(userEntrancesList) ? (
        popoverBody
      ) : (
        <Popover
          placement='bottomLeft'
          open={popoverVisible}
          content={renderSystemSwitch}
          trigger='click'
          onOpenChange={visible => {
            setPopoverVisible(visible)
          }}
        >
          {popoverBody}
        </Popover>
      )}
      {!collapsed && (
        <div className='mx8px'>
          <AekTreeSelect
            style={{ width: '100%' }}
            popupMatchSelectWidth={false}
            allowClear
            showSearch
            placeholder='搜索'
            treeData={menuList}
            treeNodeFilterProp='menuName'
            fieldNames={{
              value: 'menuId',
              label: 'menuName',
            }}
            suffixIcon={<SearchOutlined />}
            onSelect={(_, option) => {
              onClick({ key: option.featurePath })
            }}
          />
        </div>
      )}
      <Menu
        className={`flex-grow-1 overflow-y-auto ${styles.menu}`}
        mode='inline'
        items={items}
        selectedKeys={selectedKeys}
        openKeys={openKeys}
        inlineCollapsed={collapsed}
        onClick={onClick}
        onOpenChange={openkeys => {
          setOpenKeys(openkeys)
        }}
      />
    </div>
  )
}

export default connect(({ [namespace]: modelState }) => ({ modelState }))(Aside)
